package org.ws.task.netty.handler;

import com.google.common.collect.Sets;
import io.netty.channel.ChannelHandlerContext;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.ws.task.event.PushItemEvent;
import org.ws.task.event.support.PushItemEventHolder;
import org.ws.task.exception.RequestHandlerException;
import org.ws.task.item.TaskInstance;
import org.ws.task.repository.TaskRepository;
import org.ws.task.schedule.dispatcher.Dispatcher;
import org.ws.task.schedule.dispatcher.DispatcherFactory;
import org.ws.task.model.protocol.PushItemRequest;
import org.ws.task.model.protocol.PushItemResponse;
import org.ws.task.model.TaskConfig;
import org.ws.task.model.TaskItem;
import org.ws.task.netty.RequestActionHandler;
import org.ws.task.model.protocol.base.RequestAction;
import org.ws.task.model.protocol.base.RequestMessage;
import org.ws.task.model.protocol.base.ResponseMessage;
import org.ws.task.model.protocol.base.ResponseStatus;

import java.util.Collection;
import java.util.Set;

public class PushItemLeaderHandler implements RequestActionHandler<PushItemRequest<TaskItem>, PushItemResponse> {

    private static Logger log = LoggerFactory.getLogger(PushItemLeaderHandler.class.getName());

    @Override
    public RequestAction action() {
        return RequestAction.PUSH_TASK;
    }

    @Override
    public ResponseMessage<PushItemResponse> handler(ChannelHandlerContext ctx, RequestMessage<PushItemRequest<TaskItem>> requestMessage) throws RequestHandlerException {
        // 接收数据分配并推送
        PushItemRequest pushItemRequest = requestMessage.getBodyObject();
        String taskName = pushItemRequest.getTaskName();
        // 获取分发器
        TaskInstance taskInstance = TaskRepository.getInstance().getTaskInstance(taskName);
        TaskConfig.DispatchStrategy dispatchStrategy = taskInstance.getTaskConfig().getDispatchStrategy();
        TaskConfig.SendModel sendModel = taskInstance.getTaskConfig().getSendModel();
        Dispatcher dispatcher = DispatcherFactory.getInstance().getDispatcher(dispatchStrategy,sendModel);
        log.debug("[{}] -> LoadTaskStrategy:{}",taskName, dispatchStrategy);
        Collection<TaskItem> items = pushItemRequest.getItems();
        Set<Long> ids = Sets.newHashSet();
        if(CollectionUtils.isNotEmpty(items)){
            for (TaskItem item : items) {
                dispatcher.dispatch(item,taskName);
                ids.add(item.getId());
            }
            // 新任务通知
            PushItemEventHolder.getInstance().publishEvent(new PushItemEvent(taskName));
        }
        // 返回响应
        return makeResponseMessage(requestMessage.getId(),ids);
    }

    private ResponseMessage<PushItemResponse> makeResponseMessage(int requestId,Set<Long> ids){
        PushItemResponse pushItemResponse = new PushItemResponse();
        pushItemResponse.setSuccess(true);
        pushItemResponse.setItemIds(ids);

        ResponseMessage<PushItemResponse> responseMessage = new ResponseMessage<>(requestId);
        responseMessage.setBodyObject(pushItemResponse);
        responseMessage.setSuccess(true);
        responseMessage.setStatus(ResponseStatus.SUCCESS.getCode());

        return responseMessage;
    }
}
